<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\fetch\kuaishou;

use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\KuaiShouEnum;
use app\model\BatchCreateSchemaUriModel;
use app\model\ClientAccountModel;
use app\model\mongo\MongoKsPicModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\kuaishou\MaterialService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\helper\Str;
use think\Model;

final class MongoPicService extends MediaService implements MediaInterface
{
    /**
     * @var string 数据拉取key
     */
    protected const FETCH_KEY = ConfigEnum::CACHE_CONFIG[KuaiShouEnum::LIST_CONFIG_LOCK_KEY]['mongo_pic'];

    /**
     * 获取图片素材.
     *
     * @param string $advertiserId 账户id
     */
    public static function getPic(string $advertiserId = ''): bool
    {
        try {
            // 获取账户信息
            $obj = AccountService::getAccountModel(0, $advertiserId);
            if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
                return self::setError('账户数据不存在');
            }
            $userId = AccountService::getKsUserId($advertiserId);
            // 增量获取上次图片最新时间
            $lastTime = self::getLastTime($advertiserId);
            $startDate = '';
            $endDate = '';
            if ($lastTime) {
                $startDate = date('Y-m-d', $lastTime);
                $endDate = date('Y-m-d');
            }

            $redis = Cache::store('redis')->handler();
            $page = 0;
            while (true) {
                $result = self::getList($advertiserId, ++$page, $startDate, $endDate);
                if ($result === false) {
                    return false;
                }

                if (count($result['data']['details']) == 0) {
                    break;
                }
                foreach ($result['data']['details'] as $item) {
                    $item['account_id'] = $obj->getKey();
                    $item['adv_id'] = $advertiserId;
                    $item['client_id'] = $obj->getAttr('client_id');
                    $model = self::getInfo($obj->getKey(), $item['pic_id']);

                    $item['is_material'] = KuaiShouEnum::PIC_MATERIAL_DISABLE;
                    if (Str::contains($item['name'], '-')) {
                        $nameArr = explode('-', $item['name']);
                        $materialId = $nameArr[0];

                        $uriModel = (new BatchCreateSchemaUriModel())
                            ->where('advertiser_id', $advertiserId)
                            ->where('type', KuaiShouEnum::SCHEMA_PIC)
                            ->where('material_id', $materialId)
                            ->findOrEmpty();

                        if ($uriModel instanceof BatchCreateSchemaUriModel && $uriModel->getKey() > 0) {
                            $item['is_material'] = KuaiShouEnum::PIC_MATERIAL_ENABLE;
                        }
                    }

                    if (! $model instanceof MongoKsPicModel || ! $model->getKey()) {
                        $model = new MongoKsPicModel();
                        $item['create_time'] = time();
                        $item['is_sync'] = $model::SYNC_FAIL;
                        $item['is_system'] = 0;
                        if ($userId) {
                            $item['user_id'] = strval($userId);
                        }
                    }
                    if ($item['pic_type'] == 0 && ! empty($item['width']) && ! empty($item['height'])) {
                        if ($item['width'] > $item['height']) {
                            $item['pic_type'] = 6;
                        } elseif ($item['width'] < $item['height']) {
                            $item['pic_type'] = 5;
                        }
                    }
                    $item['update_time'] = time();
                    $model->setAttrs($item);
                    if (! $model->save()) {
                        throw new \Exception('保存数据出错');
                    }

                    if ($model->getAttr('is_material') == KuaiShouEnum::PIC_MATERIAL_ENABLE) {
                        $val = $advertiserId . '|||' . $model->getKey();
                        // 加入直达链接缓存队列
                        $redis->rPush(ConfigEnum::CACHE_CONFIG[KuaiShouEnum::BATCH_CONFIG_KEY]['batch_schema_pic'], $val);
                    }
                }
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 获取图片素材列表.
     *
     * @param string $advertiserId 账户id
     * @param int $page 页数
     * @return bool|mixed|string
     */
    private static function getList(string $advertiserId = '', int $page = 1, string $startDate = '', string $endDate = '')
    {
        $token = AccountService::getToken(CommonEnum::KS_MEDIA, $advertiserId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        $params = [
            'advertiser_id' => $advertiserId,
            'page' => $page,
            'page_size' => KuaiShouEnum::MAX_PAGE_SIZE,
        ];

        if ($startDate && $endDate) {
            $params['start_date'] = $startDate;
            $params['end_date'] = $endDate;
        }

        return MaterialService::getPicList($headers, $params);
    }

    /**
     * 获取组信息.
     * @param int $accountId 账户id
     * @param string $picId pic—id
     * @return null|array|mixed|Model|MongoKsPicModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getInfo(int $accountId = 0, string $picId = '')
    {
        $where = [
            ['account_id', '=', $accountId],
            ['pic_id', '=', $picId],
        ];
        return (new MongoKsPicModel())->where($where)->field(true)->find();
    }

    /**
     * 获取用户最后一个的上传时间.
     * @param string $advertiserId 账户id
     * @return mixed
     */
    private static function getLastTime(string $advertiserId = '')
    {
        return (new MongoKsPicModel())->where('adv_id', $advertiserId)->max('create_time');
    }
}
